#include <unistd.h>
#include <sys/statfs.h>
#include <sys/inotify.h>
#include "seqiot.h"
#include "sqlite.h"
#include "redis.h"
#include "sched_pub.h"
#include "hisdata.h"
#include "channel.h"

void my_test() {
//    struct statfs diskInfo;
//    statfs("/tmp", &diskInfo);
//    printf("f_bsize = %ld, f_blocks = %ld, f_bavail = %ld, f_bfree = %ld\n",
//           diskInfo.f_bsize, diskInfo.f_blocks * 4, diskInfo.f_bavail * 4, diskInfo.f_bfree * 4);

//    int fd = inotify_init();
//    int wd = inotify_add_watch(fd, "/home/jrxian", IN_CREATE | IN_DELETE | IN_MODIFY);
//
//    signal(SIGINT, sig_handler);
//    signal(SIGTERM, sig_handler);
//
//    char buf[256];
//    while (-1 != read(fd, buf, sizeof(buf))) {
//        struct inotify_event *evt = buf;
//        printf("mask=%02x, name=%s\n", evt->mask, evt->name);
//    }
//
//    inotify_rm_watch(fd, wd);
//    printf("inotify_rm_watch\n");
}

int main(int argc, char *argv[]) {
    if (argc > 1) {
        chdir(argv[1]);
    }

    log_init();
    seqiot_t *seqiot = seqiot_new();
    if (0 != read_config(seqiot, NULL, 0, -1)) {
        return EXIT_FAILURE;
    }
    if (!redis_open(seqiot->local_address)) {
        return EXIT_FAILURE;
    }

    struct timeval _tv;
    gettimeofday(&_tv, NULL);
    //必须调用一次__timezone才有值
    localtime(&_tv.tv_sec);
    for (int i = 0; i < vector_size(&seqiot->catalogs); ++i) {
        data_catalog_t *catalog = vector_get(&seqiot->catalogs, i);
        if (catalog->pub.period < 0) {
            catalog->_next_sched = _tv.tv_sec;
        } else {
            catalog->_next_sched = next_sched(_tv.tv_sec, &catalog->pub);
        }
    }

    block_params_t args = {
            .seqiot = seqiot,
            .sched_time = 0,
    };

    pub_handler_t pub_handler = {
            .handle = NULL,
            .args = &args,
            .on_filter = catalog_filter,
            .on_compare = value_changed_compare,
            .on_write = block_write,
            .on_flush = block_flush,
    };

    time_t next_sched = 0;

    while (running) {
        struct timeval _tv;
        gettimeofday(&_tv, NULL);
        args.sched_time = _tv.tv_sec;

        if (args.sched_time > next_sched) {
            next_sched = args.sched_time - (args.sched_time % (3600 * 24)) + (3600 * 16);
            if (NULL != pub_handler.handle) {
                fclose(pub_handler.handle);
            }

            struct tm _tm;
            char filename[NAME_MAX];
            localtime_r(&args.sched_time, &_tm);
            snprintf(filename, sizeof(filename), "/usr/data/hdb%04d%02d%02d.db",
                     _tm.tm_year + 1900, _tm.tm_mon + 1, _tm.tm_mday);
            pub_handler.handle = fopen(filename, "a");
            log_info("open file %s = %p", filename, pub_handler.handle);

            check_whole(&pub_handler, args.seqiot);
        } else {
            if (NULL != pub_handler.handle) {
                fclose(pub_handler.handle);
            }
            struct tm _tm;
            char filename[NAME_MAX];
            localtime_r(&args.sched_time, &_tm);
            snprintf(filename, sizeof(filename), "/usr/data/hdb%04d%02d%02d.db",
                     _tm.tm_year + 1900, _tm.tm_mon + 1, _tm.tm_mday);
            pub_handler.handle = fopen(filename, "a");
            check_next_sched(&pub_handler, args.seqiot, args.sched_time);
        }

        publish_changed(&pub_handler, args.seqiot);

        usleep(1000 * 1000);
    }

    if (NULL != pub_handler.handle) {
        fclose(pub_handler.handle);
    }

    redis_close();
    seqiot_free(seqiot);
    log_fini();

    return EXIT_SUCCESS;
}
